use std::io::{BufWriter, Write};
use std::net::TcpStream;

#[derive(Debug)]
struct MyWriter<W> {
    writer: W,
}

// 错误示例
// impl<W: Write> MyWriter<W> {
//     pub fn new(addr: &str) -> Self {
//         let stream = TcpStream::connect("127.0.0.1:8080").unwrap();
//         Self {
//             writer: BufWriter::new(stream),
//         }
//     }
//     pub fn write(&mut self, buf: &str) -> std::io::Result<()> {
//         self.writer.write_all(buf.as_bytes())
//     }
// }
// 实现 new 方法时，对泛型的约束要求要满足 W: Write，
// 而 new 的声明返回值是 Self，也就是说 self.wirter 必须是 W: Write 类型(泛型)，
// 但实际返回值是一个确定的类型 BufWriter<TcpStream>，这不满足要求。

fn main() {
    let mut writer = MyWriter::new("127.0.0.1:8080");
    let _ = writer.write("hello world!");
}

// 三种方法:
// 1.修改new的返回值
// 2.对确定的类型 MyWriter<BufWriter<TcpStream>>实现 new 方法：
// 3.修改 new 方法的实现，使用依赖注入

// 第一种
impl MyWriter<BufWriter<TcpStream>> {
    pub fn new(addr: &str) -> Self {
        let stream = TcpStream::connect(addr).unwrap();
        Self {
            writer: BufWriter::new(stream),
        }
    }
    pub fn write(&mut self, buf: &str) -> std::io::Result<()> {
        self.writer.write_all(buf.as_bytes())
    }
}

// 第二种方法
// impl MyWriter<BufWriter<TcpStream>> {
//     pub fn new(addr: &str) -> Self {
//         let stream: TcpStream = TcpStream::connect(addr).unwrap();
//         Self {
//             writer: BufWriter::new(stream),
//         }
//     }
//     pub fn write(&mut self, buf: &str) -> std::io::Result<()> {
//         self.writer.write_all(buf.as_bytes())
//     }
// }

// 第三种,依赖注入
// impl<W: Write> MyWriter<W> {
//     pub fn new(writer: W) -> Self {
//         Self { writer }
//     }
// }
